/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package fr.jade.examples.fraclite.statecontrol;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.fractal.util.Fractal;

import fr.jade.fraclite.api.State;
import fr.jade.fraclite.util.FracLite;

public class HelloWorld {

  public static void main (final String[] args) throws Exception {

    Component boot = Fractal.getBootstrapComponent();
    TypeFactory tf = Fractal.getTypeFactory(boot);
    // type of client component
    ComponentType cType = tf.createFcType(new InterfaceType[] {
      tf.createFcItfType("r", "java.lang.Runnable", false, false, false),
      tf.createFcItfType("s", "fr.jade.examples.fraclite.statecontrol.Service", true, false, false)
    });
    // type of server component
    ComponentType sType = tf.createFcType(new InterfaceType[] {
      tf.createFcItfType("s", "fr.jade.examples.fraclite.statecontrol.Service", false, false, false),
    });

    GenericFactory cf = Fractal.getGenericFactory(boot);

    // create client component
    Component cComp = cf.newFcInstance(cType, "primitive", "fr.jade.examples.fraclite.statecontrol.ClientImpl");
    // create server components
    Component sCompV1 = cf.newFcInstance(sType, "primitive", "fr.jade.examples.fraclite.statecontrol.ServerImplV1");
    Component sCompV2 = cf.newFcInstance(sType, "primitive", "fr.jade.examples.fraclite.statecontrol.ServerImplV2");
    
      // component assembly
    Fractal.getBindingController(cComp).bindFc("s", sCompV1.getFcInterface("s"));
 
    // start client component
    Fractal.getLifeCycleController(cComp).startFc();

    // call main method
    ((Runnable)cComp.getFcInterface("r")).run();
    
    // Update printer
    Fractal.getBindingController(cComp).unbindFc("s");
    
    System.out.println("Update printer V1->V2");
    State s = FracLite.getStateController(sCompV1).getState();
    FracLite.getStateController(sCompV2).setState(s);
    
    Fractal.getBindingController(cComp).bindFc("s", sCompV2.getFcInterface("s"));
    
    // call main method
    ((Runnable)cComp.getFcInterface("r")).run();
  }

}
